package com.tkk.monitoring.analyze.http;

import com.alibaba.fastjson.JSON;
import com.tkk.monitoring.analyze.config.Line;
import io.netty.handler.codec.http.HttpHeaders;
import org.apache.http.Header;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHost;
import org.apache.http.HttpResponse;
import org.apache.http.client.HttpClient;
import org.apache.http.client.config.RequestConfig;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.impl.client.HttpClientBuilder;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.message.BasicHeader;
import org.apache.http.util.EntityUtils;
import org.jsoup.nodes.Document;
import org.jsoup.select.Elements;

import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.net.URLEncoder;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * author: Tkk
 * date: 2015/7/8
 */
public class Request {

    private static Line line = new Line("proxy.txt");
    private static Pattern pattern = Pattern.compile("(http|https)://([^:]+):(\\d+)", Pattern.CASE_INSENSITIVE);

    protected CloseableHttpClient client;

    public Request() {
        HttpClientBuilder builder = HttpClientBuilder.create();
        this.client = builder.build();
    }

    /**
     * @param url
     * @param paramMap
     * @param headers
     * @return
     */
    public String getContent(String url, Map<String, Object> paramMap, HttpHeaders headers) {
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = getResponse(url, paramMap, headers);
            HttpEntity entity = httpResponse.getEntity();
            return EntityUtils.toString(entity, "UTF-8");
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (httpResponse != null)
                try {
                    httpResponse.close();
                } catch (IOException e) {
                }
        }
        return null;
    }

    /**
     *
     * @param url
     * @param paramMap
     * @param headers
     * @return
     */
    public CloseableHttpResponse getResponse(String url, Map<String, Object> paramMap, HttpHeaders headers) {
        url = toURL(url, paramMap);
        HttpGet httpGet = new HttpGet(url);
        httpGet.setConfig(getRequestConfig());
        Iterator<Map.Entry<String, String>> iterator = headers.iterator();
        while (iterator.hasNext()) {
            Map.Entry<String, String> next = iterator.next();
            httpGet.setHeader(new BasicHeader(next.getKey(), next.getValue()));
        }

        //
        CloseableHttpResponse httpResponse = null;
        try {
            httpResponse = client.execute(httpGet);
            return httpResponse;
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public CloseableHttpResponse postResponse(String uri, Map<String, Object> paramMap, HttpHeaders headers) {
        return null;
    }

    public String postContent(String uri, Map<String, Object> paramMap, HttpHeaders headers) {
        return null;
    }

    public JSON getJSON() {
        return null;
    }

    public JSON postJSON() {
        return null;
    }

    public Elements getElement() {
        return null;
    }

    public Elements postElement() {
        return null;
    }

    public static String toURL(String url, Map<String, Object> paramMap) {
        if (paramMap == null) {
            return url;
        } else {
            Set<String> paramNames = paramMap.keySet();
            StringBuilder sb = new StringBuilder(url).append("?");
            for (String paramName : paramNames) {
                try {
                    sb.append(paramName)
                            .append("=")
                            .append(URLEncoder.encode(paramMap.get(paramName).toString(), "utf-8"))
                            .append("&");
                } catch (Exception e) {
                }
            }
            return sb.toString();
        }
    }

    /**
     * @param isHttps
     * @return
     */
    public static String getProxy(boolean isHttps) {
        while (true) {
            String proxy = line.next();
            if (isHttps && proxy.startsWith("https")) {
                return proxy;
            } else if (proxy.startsWith("http")) {
                return proxy;
            }
        }
    }

    public void close() {
        if (client != null) {
            try {
                client.close();
            } catch (IOException e) {
            }
        }
    }

    /**
     * @return
     */
    protected RequestConfig getRequestConfig() {
        String proxy = Request.getProxy(false);
        Matcher matcher = pattern.matcher(proxy);
        matcher.find();
        HttpHost host = new HttpHost(matcher.group(2), Integer.parseInt(matcher.group(3)), matcher.group(1));
        return RequestConfig.custom().setProxy(host).build();
    }
}
